package file_server2

import (
	_ "embed"
	"fmt"
	"gitee.com/go-web-2/business/config"
	"gitee.com/go-web-2/business/errors/common_errors"
	"gitee.com/go-web-2/business/route"
	"gitee.com/go-web-2/web_framework/context"
	errors2 "gitee.com/go-web-2/web_framework/errors"
	"log"
	"net/http"
	"os"
	"path/filepath"
)

type downloadList struct {
	FileName    string `json:"fileName"`
	DownloadUrl string `json:"download_url"`
	PreviewUrl  string `json:"preview_url"`
}

type Downloader struct {
	dir string
}

func (d *Downloader) Download(c *context.Context) {
	fileName := c.R.URL.Query().Get("fileName")
	if fileName == "" {
		c.RespBadRequest(errors2.BadRequestError.Error())
		return
	}
	path := filepath.Join(d.dir, fileName)
	if _, err := os.Stat(path); os.IsNotExist(err) {
		log.Println(fmt.Sprintf("file %s does not exist", fileName))
		c.RespSystemErr(common_errors.FileNotFound.Error())
		return
	}

	c.W.Header().Set("Content-Disposition", "attachment; filename="+config.FileStorage[fileName])
	c.W.Header().Set("Content-Type", "application/octet-stream")

	c.SkipFlashResp = true
	http.ServeFile(c.W, c.R, path)
}

func (d *Downloader) Preview(c *context.Context) {
	fileName := c.R.URL.Query().Get("fileName")
	if fileName == "" {
		c.RespBadRequest(errors2.BadRequestError.Error())
		return
	}
	path := filepath.Join(d.dir, fileName)
	if _, err := os.Stat(path); os.IsNotExist(err) {
		log.Println(fmt.Sprintf("file %s does not exist", fileName))
		c.RespSystemErr(common_errors.FileNotFound.Error())
		return
	}

	c.SkipFlashResp = true
	http.ServeFile(c.W, c.R, path)
}

func (d *Downloader) HandleDownloadList(c *context.Context) {
	entries, err := os.ReadDir(d.dir)
	if err != nil {
		log.Println(err)
		c.RespSystemErr(errors2.ServerError.Error())
		return
	}
	fileList := make([]downloadList, 0, len(config.FileStorage))
	for _, e := range entries {
		fileName, ok := config.FileStorage[e.Name()]
		if ok {
			fileList = append(fileList, downloadList{
				FileName:    fileName,
				DownloadUrl: fmt.Sprintf("%s?fileName=%s", route.FileDownload, e.Name()),
				PreviewUrl:  fmt.Sprintf("%s?fileName=%s", route.FilePreview, e.Name()),
			})
		}
	}

	c.RespOk(fileList)
}

func NewDownloader(dir string) *Downloader {
	return &Downloader{dir: dir}
}
